#include "frame_thread_pool.h"

#include "mysql_build.h"
#include "log.h"
#include "json.h"



int exitPipe[2]; // handler只能访问全局的数据

void handler(int signum) {
    printf("Parent got signal, signum = %d\n", signum);
    write(exitPipe[1], "1", 1);
}

// ./server 192.168.142.128 12345 3 mysql密码
// ./server 192.168.142.128 12345 3 ""
int main(int argc, char *argv[]) {
    ipconfig config = read_server_config("server.json");
    pipe(exitPipe);

    pid_t pid = fork();
    if(pid != 0) {
        //printf("I am parent, pid = %d\n", getpid());
        close(exitPipe[0]); // 父进程关闭管道的读端
        signal(SIGUSR1, handler);
        wait(NULL);
        printf("Parent is going to exit!\n");
        exit(0);
    }
    //printf("I am child, pid = %d\n", getpid());
    close(exitPipe[1]);  // 子进程关闭写端

    // 建立数据库
    MYSQL *mysql = mysql_init(NULL);
    setupDatabase(mysql, config.mysqlPassward);

    // 建立用户空间，3期
    buildUserSpace();

    // 建线程池
    threadPool_t threadPool;
    int workerNumber = atoi(config.pthreadNum);
    threadPoolInit(&threadPool, workerNumber, mysql);

    // 建子线程
    makeWorker(&threadPool);

    // tcp
    int sockfd = tcpInit(config.ip, config.port);
    // epoll
    int epfd = epoll_create(1);
    epollAdd(epfd, sockfd);
    epollAdd(epfd, exitPipe[0]);

    struct epoll_event readySet[1024];
    while(1) {
        int readyNum = epoll_wait(epfd, readySet, 1024, -1);
        for(int i = 0; i < readyNum; i++) {
            if(readySet[i].data.fd == sockfd) {
                int netfd = accept(sockfd, NULL, NULL);

                pthread_mutex_lock(&threadPool.mutex);
                printf("I am master, I got a netfd = %d\n", netfd);
                enQueue(&threadPool.taskQueue, netfd);
                pthread_mutex_unlock(&threadPool.mutex);
                pthread_cond_broadcast(&threadPool.cond);
            }
            else if(readySet[i].data.fd == exitPipe[0]) {
                printf("threadPool is going to exit!\n");

                pthread_mutex_lock(&threadPool.mutex);
                threadPool.exitFlag = 1;
                pthread_mutex_unlock(&threadPool.mutex);
                pthread_cond_broadcast(&threadPool.cond);

                for(int j = 0; j < workerNumber; j++) {
                    pthread_join(threadPool.tidArr.arr[j], NULL);
                }
                threadPoolFree(&threadPool);
                close(sockfd);

                printf("All threads have exited.\n");
                exit(0);
            }
        }
    }

    mysql_close(mysql);
    close(sockfd);

    return 0;
}
